<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>12canvas折线图</title>
</head>
<style>
    canvas {
        border: 1px solid #ccc;
    }
</style>
<body>
<canvas width="600" height="400"></canvas>
<script>
    /*1.构造函数*/
    var LineChart = function (ctx) {
        /*获取绘图工具*/
        this.ctx = ctx || document.querySelector('canvas').getContext('2d');
        /*画布的大小*/
        this.canvasWidth = this.ctx.canvas.width;
        this.canvasHeight = this.ctx.canvas.height;
        /*网格的大小*/
        this.gridSize = 10;
        /*坐标系的间距*/
        this.space = 20;
        /*箭头的大小*/
        this.arrowSize = 10;
        /*确定原点的位置*/
        this.x0 = this.space - 0.5;
        this.y0 = this.canvasHeight - this.space - 0.5;
        /*绘制点的大小*/
        this.dottedSize = 4;
        /*点的坐标 和数据有关系  数据可视化*/

    };

    /*2.行为和方法*/
    LineChart.prototype.init = function (data) {
        this.drawGrid();
        this.drawAxis();
        this.drawDotted(data);
    };
    /*绘制网格*/
    LineChart.prototype.drawGrid = function () {
        /*x方向的线*/
        var xLineTotal = Math.floor(this.canvasHeight / this.gridSize);
        for (let i = 0; i < xLineTotal; i++) {
            this.ctx.beginPath();
            this.ctx.moveTo(0, i * this.gridSize - 0.5);
            this.ctx.lineTo(this.canvasWidth, i * this.gridSize - 0.5);
            this.ctx.strokeStyle = '#ddd';
            this.ctx.stroke();
        }
        /*y方向的线*/
        var yLineTotal = Math.floor(this.canvasWidth / this.gridSize);
        for (let i = 0; i < yLineTotal; i++) {
            this.ctx.beginPath();
            this.ctx.moveTo(i * this.gridSize - 0.5, 0);
            this.ctx.lineTo(i * this.gridSize - 0.5, this.canvasHeight);
            this.ctx.strokeStyle = '#ddd';
            this.ctx.stroke();
        }
    };
    /*绘制坐标系*/
    LineChart.prototype.drawAxis = function () {
        /*绘制x轴*/
        this.ctx.beginPath();
        this.ctx.moveTo(this.x0, this.y0);
        this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
        /*绘制箭头*/
        this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 - this.arrowSize / 2);
        this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 + this.arrowSize / 2);
        this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
        this.ctx.fill();
        this.ctx.strokeStyle = '#000';
        this.ctx.stroke();
        /*绘制y轴*/
        this.ctx.beginPath();
        this.ctx.moveTo(this.x0, this.y0);
        this.ctx.lineTo(this.x0, this.space);
        /*绘制箭头*/
        this.ctx.lineTo(this.x0 - this.arrowSize / 2, this.space + this.arrowSize);
        this.ctx.lineTo(this.x0 + this.arrowSize / 2, this.space + this.arrowSize);
        this.ctx.lineTo(this.x0, this.space);
        this.ctx.fill();
        this.ctx.stroke();
    };
    /*绘制点*/
    LineChart.prototype.drawDotted = function (data) {
        /*记录当前的坐标*/
        var prevCanvasX = 0;
        var prevCanvasY = 0;
        for (let i = 0; i < data.length; i++) {
            /*1.数据的坐标转换为canvas坐标系*/
            /*canvasX=原点坐标X+数据的坐标*/
            /*canvasY=原点坐标Y-数据的坐标*/
            var canvasX = this.x0 + data[i].x;
            var canvasY = this.y0 - data[i].y;
            this.ctx.beginPath();
            /*2.再进行点的绘制*/
            this.ctx.moveTo(canvasX - this.dottedSize / 2, canvasY - this.dottedSize / 2);
            this.ctx.lineTo(canvasX + this.dottedSize / 2, canvasY - this.dottedSize / 2);
            this.ctx.lineTo(canvasX + this.dottedSize / 2, canvasY + this.dottedSize / 2);
            this.ctx.lineTo(canvasX - this.dottedSize / 2, canvasY + this.dottedSize / 2);
            this.ctx.closePath();
            this.ctx.fill();
            /*3.连线*/
            if (i === 0) {
                /*当是第一个点的时候，起点是 [x0,y0]*/
                this.ctx.beginPath();
                this.ctx.moveTo(this.x0, this.y0);
                this.ctx.lineTo(canvasX, canvasY);
                this.ctx.stroke();
            } else {
                /*不是第一个点的时候，起点是上一个点*/
                this.ctx.beginPath();
                // this.ctx.moveTo(this.x0 + data[i - 1].x, this.y0 - data[i - 1].y);
                this.ctx.moveTo(prevCanvasX, prevCanvasY);
                this.ctx.lineTo(canvasX, canvasY);
                this.ctx.stroke();
            }
            /*记录当前坐标,连接下一个点的时候需要*/
            prevCanvasX = canvasX;
            prevCanvasY = canvasY;
        }
    };
    /*3.初始化*/
    var data = [{x: 50, y: 151}, {x: 100, y: 236}, {x: 150, y: 171}, {x: 200, y: 276}, {x: 250, y: 251}, {
        x: 300,
        y: 367
    }, {x: 350, y: 377}, {x: 400, y: 328}, {x: 450, y: 277}, {x: 500, y: 122}];
    var lineChart = new LineChart();
    lineChart.init(data);
</script>
</body>
</html>

